var Validate = function() {
	// Private Variables
	var errorClassName = "error";
	var labelSuffix = "Label";
	var messageSuffix = "Error";
	
	// Private Methods
	function hasValue(field) {
		if (field && field.value && field.value != null) {
			return true;
		}
		return false;
	}
	function addError(labelEl, msgEl, msg) {
		labelEl.addClass(errorClassName);
		var fullMsg = msgEl.html() + ' ' + msg;
		msgEl.addClass(errorClassName)
			.html(fullMsg)
			.css('visibility', 'visible');
	}
	function removeError(labelEl, msgEl) {
		labelEl.removeClass(this.errorClassName);
		msgEl.html('')
			.css('visibility', 'hidden');
	}

	// Public Methods
	return {
		setMessageSuffix: function(suffix) {
			messageSuffix = suffix;
		},
		getMessageSuffix: function() {
			return messageSuffix;
		},
		setLabelSuffix: function(suffix) {
			labelSuffix = suffix;
		},
		getLabelSuffix: function() {
			return labelSuffix;
		},
		setErrorClassName: function(clazzName) {
			this.errorClassName = clazzName;
		},
		getErrorClassName: function() {
			return this.errorClassName;
		},
		clearMessages: function(field) {
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			removeError(label, error);
		},
		isEmpty: function(field, msg){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field) || field.value == "") {
				addError(label, error, msg);
				return true;
			}
			return false;
		},
		isStringEmpty: function(field, msg){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field) || field.value == '' || $.trim(field.value).length == 0) {
				addError(label, error, msg);
				return true;
			}
			return false;
		},
		isStringInRange: function(field, msg, minLength, maxLength, trimString){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field)) {
				addError(label, error, msg);
				return false;
			}
			var value = field.value;
			if (trimString && trimString == true) {
				value = $.trim(field.value);
			}
			if ((minLength > -1 && minLength > value.length) || (maxLength > -1 && maxLength < value.length)) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		isIntInRange: function(field, msg, minLength, maxLength){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field)) {
				addError(label, error, msg);
				return false;
			}
			var value = parseInt(field.value);
			if (minLength != null && value < minLength) {
				addError(label, error, msg);
				return false;
			}
			if (maxLength != null && value > maxLength) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		isFloatInRange: function(field, msg, minLength, maxLength){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field)) {
				addError(label, error, msg);
				return false;
			}
			var value = parseFloat(field.value);
			if (minLength != null && value < minLength) {
				addError(label, error, msg);
				return false;
			}
			if (maxLength != null && value > maxLength) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		isFloatInRangeExclusive: function(field, msg, minLength, maxLength){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (!hasValue(field)) {
				addError(label, error, msg);
				return false;
			}
			var value = parseFloat(field.value);
			if (minLength != null && value <= minLength) {
				addError(label, error, msg);
				return false;
			}
			if (maxLength != null && value >= maxLength) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		matchesFieldExpression: function(form, field, msg, expression) {
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			var pattern = /^(\w+)\.equals\((\w+)\)$/;
			if (expression && pattern.test(expression)) {
				var results = expression.match(pattern);
				if (results.length == 3) {
					var value1 = $(form.elements[results[1]]).val();
					var value2 = $(form.elements[results[2]]).val();
					if (value1 != value2) {
						addError(label, error, msg);
						return false;
					}
				}
			}
			return true;
		},
		matchesRegEx: function(field, msg, regex){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			if (hasValue(field) && !field.value.match(regex)) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		isEmail: function(field, msg){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			var filter = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
			if (hasValue(field) && !filter.test(field.value)) {
				addError(label, error, msg);
				return false;
			}
			return true;
		},
		isUrl: function(field, msg){
			var label = $('#' + field.id + labelSuffix);
			var error = $('#' + field.id + messageSuffix);
			var filter = /(^(ftp|http|https):\/\/(\.[_A-Za-z0-9-]+)*(@?([A-Za-z0-9-])+)?(\.[A-Za-z0-9-]+)*((\.[A-Za-z0-9]{2,})|(\.[A-Za-z0-9]{2,}\.[A-Za-z0-9]{2,}))(:[0-9]+)?([\/A-Za-z0-9?#_-]*)?$)/gi;
			if (hasValue(field) && !filter.test(field.value)) {
				addError(label, error, msg);
				return false;
			}
			return true;
		}
	}
}();

